若依框架中权限管理的后端实现 | 您所在的位置:网站首页 › 若依 权限字符 › 若依框架中权限管理的后端实现 |
文章目录
RBAC模型介绍权限的分类菜单权限和按钮权限的实现接口权限的实现数据权限的实现
RBAC模型介绍
若依框架的权限管理功能是基于RBAC模型来实现的,即:系统中所有的权限,都是基于角色来控制的框架对权限的控制,不仅支持菜单的功能,还支持菜单中每一个按钮的权限控制
RBAC模型包含的表有下面五张: 1. 用户表 2. 角色表 3. 权限菜单表 4. 用户和角色的关联表 5. 角色和权限菜单的关联表 关系如下: 具体代码如下: controller层:SysLoginController下的getRouters()方法 /** * 获取路由信息 * * @return 路由信息 */ @GetMapping("getRouters") public AjaxResult getRouters() { Long userId = SecurityUtils.getUserId(); List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); }service层:SysMenuServiceImpl下的selectMenuTreeByUserId()方法 /** * 根据用户ID查询菜单 * * @param userId 用户名称 * @return 菜单列表 */ @Override public List selectMenuTreeByUserId(Long userId) { List menus = null; if (SecurityUtils.isAdmin(userId)) { menus = menuMapper.selectMenuTreeAll(); } else { menus = menuMapper.selectMenuTreeByUserId(userId); } return getChildPerms(menus, 0); }先判断用户是否为超级管理员,若是,则返回所有权限菜单,若不是,则根据用户id返回菜单 mapper层:SysMenuMapper 超级管理员执行的sql /** * 根据用户ID查询菜单 * * @return 菜单列表 */ public List selectMenuTreeAll(); select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0 order by m.parent_id, m.order_num其他用户执行的sql /** * 根据用户ID查询菜单 * * @param userId 用户ID * @return 菜单列表 */ public List selectMenuTreeByUserId(Long userId); select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_user_role ur on rm.role_id = ur.role_id left join sys_role ro on ur.role_id = ro.role_id where ur.user_id = #{params.userId} AND m.menu_name like concat('%', #{menuName}, '%') AND m.visible = #{visible} AND m.status = #{status} order by m.parent_id, m.order_num 接口权限的实现以获取用户列表的接口为例 /** * 获取用户列表 */ @PreAuthorize("@ss.hasPermi('system:user:list')") @GetMapping("/list") public TableDataInfo list(SysUser user) { startPage(); List list = userService.selectUserList(user); return getDataTable(list); }接口权限是基于SpringSecurity的注解@PreAuthorize实现的 若依框架在PermissionService中重新定义了hasPermi()方法 /** * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 * * @author ruoyi */ @Service("ss") public class PermissionService { . . . /** * 验证用户是否具备某权限 * * @param permission 权限字符串 * @return 用户是否具备某权限 */ public boolean hasPermi(String permission) { if (StringUtils.isEmpty(permission)) { return false; } LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; } PermissionContextHolder.setContext(permission); return hasPermissions(loginUser.getPermissions(), permission); } . . . }每次带有注解@PreAuthorize的请求过来,就会先执行hasPermi(),判断是否具备某权限,若返回false则没有权限,若返回true,则有权限,可以执行该接口 数据权限的实现数据权限的核心就是使用aop切面,拼接sql语句 通过监听这个注解来执行切面,DataScopeAspect为定义切面的类 这里的基本思想就是把要拼接的sql语句传到基类中的params里,params是BaseEntity类中的一个map类型的属性 数据权限分为五种,分别是全部数据权限、自定数据权限、部门数据权限、部门及以下数据权限、仅本人数据权限,拼接对应的sql语句 |
CopyRight 2018-2019 实验室设备网 版权所有 |